package com.reebake.ideal.user.controller.client;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.reebake.ideal.user.client.UserDetailsClient;
import com.reebake.ideal.user.entity.UserCredential;
import com.reebake.ideal.user.entity.UserDetailsDTO;
import com.reebake.ideal.user.entity.UserRegisterDTO;
import com.reebake.ideal.user.properties.UserProperties;
import com.reebake.ideal.user.service.UserAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;

@RestController
@RequestMapping("client/user-details")
public class UserDetailsClientController implements UserDetailsClient {
	
	@Autowired
	private UserAuthService userAuthService;
	@Autowired
	private UserProperties userProperties;

	@Override
	public UserDetailsDTO loadUserByUserId(String userId) {
		UserCredential userCredential = userAuthService.queryByUserId(userId);
		return toUserDetails(userCredential);
	}

	@Override
	public UserDetailsDTO loadUserByUsername(String username) {
		UserCredential userCredential = userAuthService.queryByUsername(username);
		UserDetailsDTO userDetailsDTO = toUserDetails(userCredential);
		userDetailsDTO.setPassword(userCredential.getPassword());
		return userDetailsDTO;
	}

	@Override
	public UserDetailsDTO loadUserByPhoneNumber(String phoneNumber) {
		UserCredential userCredential = userAuthService.queryByPhoneNumber(phoneNumber);
        return toUserDetails(userCredential);
	}

	@Override
	public UserDetailsDTO loadUserByEmail(String email) {
		UserCredential userCredential = userAuthService.queryByEmail(email);
		if(ObjUtil.isNotNull(userCredential)) {
			userCredential.setUsername(email);// 使用email充当username
		}
		return toUserDetails(userCredential);
	}

	@Override
	public UserDetailsDTO loadUserByThirdParty(String uuid, String source) {
		UserCredential userCredential = userAuthService.queryByThirdParty(uuid, source);
		return toUserDetails(userCredential);
	}

	public UserDetailsDTO toUserDetails(UserCredential userCredential) {
		if(userCredential == null) {
			return null;
		}
		String userId = userCredential.getUserId();
		String userCredentialId = userCredential.getUserCredentialId();
		Collection<String> authorities = CollectionUtil.newArrayList();

		boolean accountEnabled = userCredential.getAccountEnabled();
		boolean accountNonExpired = userCredential.getAccountNonExpired();
		boolean accountNonLocked = userCredential.getAccountNonLocked();
		boolean credentialsNonExpired = userCredential.getCredentialsNonExpired();

		UserDetailsDTO userDetails = new UserDetailsDTO();
		userDetails.setUserId(userId);
		userDetails.setUserCredentialId(userCredentialId);
		userDetails.setAuthorities(authorities);
		userDetails.setEnabled(accountEnabled);
		userDetails.setAccountNonExpired(accountNonExpired);
		userDetails.setCredentialsNonExpired(credentialsNonExpired);
		userDetails.setAccountNonLocked(accountNonLocked);

		return userDetails;
	}

	@Override
	public String register(UserRegisterDTO userRegisterDTO) {
		if(StrUtil.isNotBlank(userRegisterDTO.getPhoneNumber())){
			return userAuthService.registerByPhoneNumber(userRegisterDTO.getPhoneNumber(), userRegisterDTO.getVerifyCode());
		}if(StrUtil.isNotBlank(userRegisterDTO.getEmail())){
			return userAuthService.registerByEmail(userRegisterDTO.getEmail(), userRegisterDTO.getVerifyCode());
		}else if(StrUtil.isNotBlank(userRegisterDTO.getUsername())) {
			return userAuthService.registerByUsername(userRegisterDTO.getUsername(), userRegisterDTO.getPassword());
		}else {
			throw new UnsupportedOperationException();
		}
	}

	@Override
	public String simpleRegister(String id) {
		if(Validator.isMobile(id)) {
			UserCredential userCredential = new UserCredential();
			userCredential.setPhoneNumber(id);
			return userAuthService.register(null, userCredential);
		}else if(Validator.isEmail(id)) {
			UserCredential userCredential = new UserCredential();
			userCredential.setEmail(id);
			return userAuthService.register(null, userCredential);
		}else {
			throw new UnsupportedOperationException();
		}
	}

	@Override
	public Boolean existsByUsername(String username) {
		return userAuthService.existsByUsername(username);
	}

	@Override
	public Boolean existsByPhoneNumber(String phoneNumber) {
		return userAuthService.existsByPhoneNumber(phoneNumber);
	}

	@Override
	public Boolean existsByEmail(String email) {
		return userAuthService.existsByEmail(email);
	}

	@Override
	public Boolean existsByThirdParty(String uuid, String source) {
		return userAuthService.existsByThirdParty(uuid, source);
	}

	@Override
	public void bindThirdPartyUser(String userId, String uuid, String source) {
		userAuthService.bindThirdPartyUser(userId, uuid, source);
	}

	@Override
	public void lock(String username) {
		UserCredential userCredential;
		if(Validator.isMobile(username)) {
			userCredential = userAuthService.queryByPhoneNumber(username);
		}else if(Validator.isEmail(username)) {
			userCredential = userAuthService.queryByEmail(username);
		}else {
			userCredential = userAuthService.queryByUsername(username);
		}
		String userId = userCredential.getUserId();
		userAuthService.lockByUserId(userId);
	}
}
